1 using System;
2 using
System.Collections.Generic;
3 using
UnityEngine;
4 using
UnityEngine.Assertions;
5 using
Random = UnityEngine.Random;
6
7 namespace
ProceduralToolkit.Examples
8 {

9     ///
<summary>
10     ///
A maze generator
11     ///
</summary>
12     
public class MazeGenerator
13     {
14         
public enum Algorithm
15         {
16             RandomTraversal,
17             RandomDepthFirstTraversal,
18             RandomBreadthFirstTraversal,
19         }
20
21         
[Serializable]
22         
public class Config
23         {
24             
public int mazeWidth = 256;
25             
public int mazeHeight = 256;
26             
public int cellSize = 2;
27             
public int wallSize = 1;
28             
public Algorithm algorithm = Algorithm.RandomTraversal;
29             
public Action<Edge> drawEdge = edge => { };
30         }
31
32         
private readonly Maze maze;
33         
private readonly List<Edge> edges;
34         
private readonly Config config;
35
36         
public MazeGenerator(Config config)
37         {
38             Assert.IsTrue(config.mazeWidth >
0);
39             Assert.IsTrue(config.mazeHeight >
0);
40             Assert.IsTrue(config.cellSize >
0);
41             Assert.IsTrue(config.wallSize >=
0);
42             Assert.IsNotNull(config.drawEdge);
43
44             
this.config = config;
45             
int widthInCells = (config.mazeWidth - config.wallSize)/(config.cellSize + config.wallSize);
46             
int heightInCells = (config.mazeHeight - config.wallSize)/(config.cellSize + config.wallSize);
47             maze =
new Maze(widthInCells, heightInCells);
48
49             
var origin = new Cell
50             {
51                 x = Random.Range(
0, widthInCells),
52                 y = Random.Range(
0, heightInCells)
53             };
54             maze[origin] = Directions.None;
55             edges =
new List<Edge>(maze.GetEdges(origin));
56         }
57
58         
public bool Generate(int steps = 0)
59         {
60             
bool changed = false;
61             
for (int i = 0; edges.Count > 0 && (steps == 0 || i < steps); i++)
62             {
63                 
switch (config.algorithm)
64                 {
65                     
case Algorithm.RandomTraversal:
66                         RandomTraversal();
67                         
break;
68                     
case Algorithm.RandomDepthFirstTraversal:
69                         RandomDepthFirstTraversal();
70                         
break;
71                     
case Algorithm.RandomBreadthFirstTraversal:
72                         RandomBreadthFirstTraversal();
73                         
break;
74                     
default:
75                         RandomTraversal();
76                         
break;
77                 }
78                 changed =
true;
79             }
80             
return changed;
81         }
82
83         
private void RandomTraversal()
84         {
85             Edge passage = edges.PopRandom();
86
87             
if (maze[passage.exit] == Directions.None)
88             {
89                 maze.AddEdge(passage);
90                 edges.AddRange(maze.GetEdges(passage.exit));
91
92                 config.drawEdge(passage);
93             }
94         }
95
96         
private void RandomDepthFirstTraversal()
97         {
98             Edge edge = edges[edges.Count -
1];
99             edges.RemoveAt(edges.Count -
1);
100
101             
if (maze[edge.exit] == Directions.None)
102             {
103                 maze.AddEdge(edge);
104                 List<Edge> newEdges = maze.GetEdges(edge.exit);
105                 newEdges.Shuffle();
106                 edges.AddRange(newEdges);
107
108                 config.drawEdge(edge);
109             }
110         }
111
112         
private void RandomBreadthFirstTraversal()
113         {
114             Edge edge = edges[
0];
115             edges.RemoveAt(
0);
116
117             
if (maze[edge.exit] == Directions.None)
118             {
119                 maze.AddEdge(edge);
120                 List<Edge> newEdges = maze.GetEdges(edge.exit);
121                 newEdges.Shuffle();
122                 edges.AddRange(newEdges);
123
124                 config.drawEdge(edge);
125             }
126         }
127     }
128 }


Gõ tìm kiếm nhanh...